#pragma once
#ifndef TEXTENSION_H
#define TEXTENSION_H
#include "TInfo.h"
#include <vector>

namespace Turbo
{
	namespace Core
	{
		typedef enum class TExtensionType
		{
			UNDEFINED = 0,
			VK_KHR_16BIT_STORAGE,
			VK_KHR_8BIT_STORAGE,
			VK_KHR_ANDROID_SURFACE,
			VK_KHR_BIND_MEMORY2,
			VK_KHR_BUFFER_DEVICE_ADDRESS,
			VK_KHR_COPY_COMMANDS2,
			VK_KHR_CREATE_RENDERPASS2,
			VK_KHR_DEDICATED_ALLOCATION,
			VK_KHR_DEFERRED_HOST_OPERATIONS,
			VK_KHR_DEPTH_STENCIL_RESOLVE,
			VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE,
			VK_KHR_DEVICE_GROUP,
			VK_KHR_DEVICE_GROUP_CREATION,
			VK_KHR_DISPLAY,
			VK_KHR_DISPLAY_SWAPCHAIN,
			VK_KHR_DRAW_INDIRECT_COUNT,
			VK_KHR_DRIVER_PROPERTIES,
			VK_KHR_EXTERNAL_FENCE,
			VK_KHR_EXTERNAL_FENCE_CAPABILITIES,
			VK_KHR_EXTERNAL_FENCE_FD,
			VK_KHR_EXTERNAL_FENCE_WIN32,
			VK_KHR_EXTERNAL_MEMORY,
			VK_KHR_EXTERNAL_MEMORY_CAPABILITIES,
			VK_KHR_EXTERNAL_MEMORY_FD,
			VK_KHR_EXTERNAL_MEMORY_WIN32,
			VK_KHR_EXTERNAL_SEMAPHORE,
			VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES,
			VK_KHR_EXTERNAL_SEMAPHORE_FD,
			VK_KHR_EXTERNAL_SEMAPHORE_WIN32,
			VK_KHR_GET_DISPLAY_PROPERTIES2,
			VK_KHR_GET_MEMORY_REQUIREMENTS2,
			VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES2,
			VK_KHR_GET_SURFACE_CAPABILITIES2,
			VK_KHR_IMAGE_FORMAT_LIST,
			VK_KHR_IMAGELESS_FRAMEBUFFER,
			VK_KHR_INCREMENTAL_PRESENT,
			VK_KHR_MAINTENANCE1,
			VK_KHR_MAINTENANCE2,
			VK_KHR_MAINTENANCE3,
			VK_KHR_MULTIVIEW,
			VK_KHR_PERFORMANCE_QUERY,
			VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES,
			VK_KHR_PIPELINE_LIBRARY,
			VK_KHR_PORTABILITY_SUBSET,
			VK_KHR_PUSH_DESCRIPTOR,
			VK_KHR_RAY_TRACING,
			VK_KHR_RELAXED_BLOCK_LAYOUT,
			VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE,
			VK_KHR_SAMPLER_YCBCR_CONVERSION,
			VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS,
			VK_KHR_SHADER_ATOMIC_INT64,
			VK_KHR_SHADER_CLOCK,
			VK_KHR_SHADER_DRAW_PARAMETERS,
			VK_KHR_SHADER_FLOAT16_INT8,
			VK_KHR_SHADER_FLOAT_CONTROLS,
			VK_KHR_SHADER_NON_SEMANTIC_INFO,
			VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES,
			VK_KHR_SHARED_PRESENTABLE_IMAGE,
			VK_KHR_SPIRV_1_4,
			VK_KHR_STORAGE_BUFFER_STORAGE_CLASS,
			VK_KHR_SURFACE,
			VK_KHR_SURFACE_PROTECTED_CAPABILITIES,
			VK_KHR_SWAPCHAIN,
			VK_KHR_SWAPCHAIN_MUTABLE_FORMAT,
			VK_KHR_TIMELINE_SEMAPHORE,
			VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT,
			VK_KHR_VARIABLE_POINTERS,
			VK_KHR_VULKAN_MEMORY_MODEL,
			VK_KHR_WAYLAND_SURFACE,
			VK_KHR_WIN32_KEYED_MUTEX,
			VK_KHR_WIN32_SURFACE,
			VK_KHR_XCB_SURFACE,
			VK_KHR_XLIB_SURFACE,
			VK_EXT_4444_FORMATS,
			VK_EXT_ACQUIRE_XLIB_DISPLAY,
			VK_EXT_ASTC_DECODE_MODE,
			VK_EXT_BLEND_OPERATION_ADVANCED,
			VK_EXT_BUFFER_DEVICE_ADDRESS,
			VK_EXT_CALIBRATED_TIMESTAMPS,
			VK_EXT_CONDITIONAL_RENDERING,
			VK_EXT_CONSERVATIVE_RASTERIZATION,
			VK_EXT_CUSTOM_BORDER_COLOR,
			VK_EXT_DEBUG_MARKER,
			VK_EXT_DEBUG_REPORT,
			VK_EXT_DEBUG_UTILS,
			VK_EXT_DEPTH_CLIP_ENABLE,
			VK_EXT_DEPTH_RANGE_UNRESTRICTED,
			VK_EXT_DESCRIPTOR_INDEXING,
			VK_EXT_DEVICE_MEMORY_REPORT,
			VK_EXT_DIRECT_MODE_DISPLAY,
			VK_EXT_DIRECTFB_SURFACE,
			VK_EXT_DISCARD_RECTANGLES,
			VK_EXT_DISPLAY_CONTROL,
			VK_EXT_DISPLAY_SURFACE_COUNTER,
			VK_EXT_EXTENDED_DYNAMIC_STATE,
			VK_EXT_EXTERNAL_MEMORY_DMA_BUF,
			VK_EXT_EXTERNAL_MEMORY_HOST,
			VK_EXT_FILTER_CUBIC,
			VK_EXT_FRAGMENT_DENSITY_MAP,
			VK_EXT_FRAGMENT_DENSITY_MAP2,
			VK_EXT_FRAGMENT_SHADER_INTERLOCK,
			VK_EXT_FULL_SCREEN_EXCLUSIVE,
			VK_EXT_GLOBAL_PRIORITY,
			VK_EXT_HDR_METADATA,
			VK_EXT_HEADLESS_SURFACE,
			VK_EXT_HOST_QUERY_RESET,
			VK_EXT_IMAGE_DRM_FORMAT_MODIFIER,
			VK_EXT_IMAGE_ROBUSTNESS,
			VK_EXT_INDEX_TYPE_UINT8,
			VK_EXT_INLINE_UNIFORM_BLOCK,
			VK_EXT_LINE_RASTERIZATION,
			VK_EXT_MEMORY_BUDGET,
			VK_EXT_MEMORY_PRIORITY,
			VK_EXT_METAL_SURFACE,
			VK_EXT_PCI_BUS_INFO,
			VK_EXT_PIPELINE_CREATION_CACHE_CONTROL,
			VK_EXT_PIPELINE_CREATION_FEEDBACK,
			VK_EXT_POST_DEPTH_COVERAGE,
			VK_EXT_PRIVATE_DATA,
			VK_EXT_QUEUE_FAMILY_FOREIGN,
			VK_EXT_ROBUSTNESS2,
			VK_EXT_SAMPLE_LOCATIONS,
			VK_EXT_SAMPLER_FILTER_MINMAX,
			VK_EXT_SCALAR_BLOCK_LAYOUT,
			VK_EXT_SEPARATE_STENCIL_USAGE,
			VK_EXT_SHADER_ATOMIC_FLOAT,
			VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION,
			VK_EXT_SHADER_IMAGE_ATOMIC_INT64,
			VK_EXT_SHADER_STENCIL_EXPORT,
			VK_EXT_SHADER_SUBGROUP_BALLOT,
			VK_EXT_SHADER_SUBGROUP_VOTE,
			VK_EXT_SHADER_VIEWPORT_INDEX_LAYER,
			VK_EXT_SUBGROUP_SIZE_CONTROL,
			VK_EXT_SWAPCHAIN_COLORSPACE,
			VK_EXT_TEXEL_BUFFER_ALIGNMENT,
			VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR,
			VK_EXT_TOOLING_INFO,
			VK_EXT_TRANSFORM_FEEDBACK,
			VK_EXT_VALIDATION_CACHE,
			VK_EXT_VALIDATION_FEATURES,
			VK_EXT_VALIDATION_FLAGS,
			VK_EXT_VERTEX_ATTRIBUTE_DIVISOR,
			VK_EXT_YCBCR_IMAGE_ARRAYS,
			VK_AMD_BUFFER_MARKER,
			VK_AMD_DEVICE_COHERENT_MEMORY,
			VK_AMD_DISPLAY_NATIVE_HDR,
			VK_AMD_DRAW_INDIRECT_COUNT,
			VK_AMD_GCN_SHADER,
			VK_AMD_GPU_SHADER_HALF_FLOAT,
			VK_AMD_GPU_SHADER_INT16,
			VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR,
			VK_AMD_MIXED_ATTACHMENT_SAMPLES,
			VK_AMD_NEGATIVE_VIEWPORT_HEIGHT,
			VK_AMD_PIPELINE_COMPILER_CONTROL,
			VK_AMD_RASTERIZATION_ORDER,
			VK_AMD_SHADER_BALLOT,
			VK_AMD_SHADER_CORE_PROPERTIES,
			VK_AMD_SHADER_CORE_PROPERTIES2,
			VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER,
			VK_AMD_SHADER_FRAGMENT_MASK,
			VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD,
			VK_AMD_SHADER_INFO,
			VK_AMD_SHADER_TRINARY_MINMAX,
			VK_AMD_TEXTURE_GATHER_BIAS_LOD,
			VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER,
			VK_FUCHSIA_IMAGEPIPE_SURFACE,
			VK_GGP_FRAME_TOKEN,
			VK_GGP_STREAM_DESCRIPTOR_SURFACE,
			VK_GOOGLE_DECORATE_STRING,
			VK_GOOGLE_DISPLAY_TIMING,
			VK_GOOGLE_HLSL_FUNCTIONALITY1,
			VK_GOOGLE_USER_TYPE,
			VK_IMG_FILTER_CUBIC,
			VK_IMG_FORMAT_PVRTC,
			VK_INTEL_PERFORMANCE_QUERY,
			VK_INTEL_SHADER_INTEGER_FUNCTIONS2,
			VK_MVK_IOS_SURFACE,
			VK_MVK_MACOS_SURFACE,
			VK_NN_VI_SURFACE,
			VK_NV_CLIP_SPACE_W_SCALING,
			VK_NV_COMPUTE_SHADER_DERIVATIVES,
			VK_NV_COOPERATIVE_MATRIX,
			VK_NV_CORNER_SAMPLED_IMAGE,
			VK_NV_COVERAGE_REDUCTION_MODE,
			VK_NV_DEDICATED_ALLOCATION,
			VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING,
			VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS,
			VK_NV_DEVICE_DIAGNOSTICS_CONFIG,
			VK_NV_DEVICE_GENERATED_COMMANDS,
			VK_NV_EXTERNAL_MEMORY,
			VK_NV_EXTERNAL_MEMORY_CAPABILITIES,
			VK_NV_EXTERNAL_MEMORY_WIN32,
			VK_NV_FILL_RECTANGLE,
			VK_NV_FRAGMENT_COVERAGE_TO_COLOR,
			VK_NV_FRAGMENT_SHADER_BARYCENTRIC,
			VK_NV_FRAMEBUFFER_MIXED_SAMPLES,
			VK_NV_GEOMETRY_SHADER_PASSTHROUGH,
			VK_NV_GLSL_SHADER,
			VK_NV_MESH_SHADER,
			VK_NV_RAY_TRACING,
			VK_NV_REPRESENTATIVE_FRAGMENT_TEST,
			VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE,
			VK_NV_SCISSOR_EXCLUSIVE,
			VK_NV_SHADER_IMAGE_FOOTPRINT,
			VK_NV_SHADER_SM_BUILTINS,
			VK_NV_SHADER_SUBGROUP_PARTITIONED,
			VK_NV_SHADING_RATE_IMAGE,
			VK_NV_VIEWPORT_ARRAY2,
			VK_NV_VIEWPORT_SWIZZLE,
			VK_NV_WIN32_KEYED_MUTEX,
			VK_NVX_IMAGE_VIEW_HANDLE,
			VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES,
			VK_QCOM_RENDER_PASS_SHADER_RESOLVE,
			VK_QCOM_RENDER_PASS_STORE_OPS,
			VK_QCOM_RENDER_PASS_TRANSFORM
		} TExtensionTypeEnum;

		class TLayerInfo;
		class TPhysicalDevice;

		class TExtensionInfo : public TInfo
		{
		public:
			friend class TLayerInfo;
			friend class TInstanceCreateInfo;
			friend class TDeviceCreateInfo;
			friend class TPhysicalDeviceProxy; //�Ƿ�û��

		private:
			TExtensionType extensionType;
			std::string name;
			uint32_t version;

		public:
			static size_t GetInstanceExtensionCount(TLayerInfo *layer = nullptr);
			static std::vector<TExtensionInfo> GetInstanceExtensions(TLayerInfo *layer = nullptr);

			static size_t GetPhysicalDeviceExtensionCount(TPhysicalDevice *physicalDevice, TLayerInfo *layer = nullptr);
			static std::vector<TExtensionInfo> GetPhysicalDeviceExtensions(TPhysicalDevice *physicalDevice, TLayerInfo *layer = nullptr);

			static TExtensionType GetExtensionTypeByExtensionName(std::string extensionName);
			static std::string GetExtensionNameByExtensionType(TExtensionType extensionType);

			static bool IsSupportPhysicalDeviceExtension(TPhysicalDevice *physicalDevice, TExtensionType extensionType);

		public:
			explicit TExtensionInfo();
			~TExtensionInfo();

		public:
			TExtensionType GetExtensionType();
			const std::string& GetName();
			uint32_t GetVersion();

			bool operator==(const TExtensionInfo &extension) const;
			bool operator!=(const TExtensionInfo &extension) const;

			virtual std::string ToString() override;
		};
	}
}
#endif // !TEXTENSION_H